home *** CD-ROM | disk | FTP | other *** search
/ Garbo / Garbo.cdr / mac / hypercrd / xcmd / dxcmds34.sit / Dartmouth XCMD's 3.4.3 / card_5128.txt < prev    next >
Text File  |  1990-04-17  |  14KB  |  436 lines

  1. -- card: 5128 from stack: in.3
  2. -- bmap block id: 0
  3. -- flags: 4000
  4. -- background id: 3241
  5. -- name: WriteToFile
  6. ----- HyperTalk script -----
  7. on Install
  8.   get ChooseTargetStack()
  9.   InstallResource XCMD,WriteToFile,it
  10. end Install
  11.  
  12.  
  13. -- part 1 (button)
  14. -- low flags: 00
  15. -- high flags: A003
  16. -- rect: left=79 top=300 right=322 bottom=179
  17. -- title width / last selected line: 0
  18. -- icon id / first selected line: 0 / 0
  19. -- text alignment: 1
  20. -- font id: 0
  21. -- text size: 12
  22. -- style flags: 0
  23. -- line height: 16
  24. -- part name: WriteToFile
  25. ----- HyperTalk script -----
  26. on mouseUp
  27.   WriteToFile field 1,FALSE,"WriteToFile Docs",FALSE,"MSWD"
  28.   put the result
  29. end mouseUp
  30.  
  31.  
  32.  
  33. -- part 7 (field)
  34. -- low flags: 81
  35. -- high flags: 2007
  36. -- rect: left=12 top=26 right=298 bottom=491
  37. -- title width / last selected line: 0
  38. -- icon id / first selected line: 0 / 0
  39. -- text alignment: 0
  40. -- font id: 22
  41. -- text size: 10
  42. -- style flags: 0
  43. -- line height: 13
  44. -- part name: Source
  45.  
  46.  
  47. -- part 8 (button)
  48. -- low flags: 00
  49. -- high flags: A003
  50. -- rect: left=299 top=300 right=322 bottom=438
  51. -- title width / last selected line: 0
  52. -- icon id / first selected line: 0 / 0
  53. -- text alignment: 1
  54. -- font id: 0
  55. -- text size: 12
  56. -- style flags: 0
  57. -- line height: 16
  58. -- part name: Show Pascal Source
  59. ----- HyperTalk script -----
  60. on mouseUp
  61.   set the visible of card field 1 to not the visible of card field 1
  62.   if the visible of card field 1 is true then
  63.     set the name of me to "Hide Pascal Source"
  64.   else set the name of me to "Show Pascal Source"
  65. end mouseUp
  66.  
  67.  
  68.  
  69. -- part contents for background part 16
  70. ----- text -----
  71. WRITETOFILE XCMD version 1.0
  72. Kevin Calhoun
  73.  
  74. The WriteToFile XCMD writes the contents of a HyperCard container to a text file.  The file may be designated by its full pathname, or it may be given by the user in a standard file dialog.  WriteToFile can append to an existing file, replace an existing file, or create a new file.
  75.  
  76. Use some caution when using WriteToFile.  It will overwrite or append to a file you designate by full pathname even if that file is better off left alone.  It does not check whether an existing file is a TEXT file.
  77.  
  78. If an error occurs, WriteToFile returns an error message as the Result.  Word 1 of this message will be "Error."  If the file was written successfully, WriteToFile returns the full pathname of the file as the Result.
  79.  
  80. INVOKING WRITETOFILE
  81.  
  82. WriteToFile container,<usePathname>,<"name">,<append>,<creator>
  83.  
  84. The first parameter, container, is the name of a HyperTalk container.  This can be a field, a variable, a function, or, in sum, anything you can "get".  For example, 
  85.  
  86.    WriteToFile card field 1
  87.  
  88. will write the contents of card field 1 to a file, while
  89.  
  90.   WriteToFile containerName
  91.  
  92. will write the contents of the HyperTalk variable called "containerName" to a file.
  93.  
  94. The second parameter, usePathname, tells WriteToFile how to interpret the third parameter.  If usePathname is TRUE, WriteToFile attempts to write to the file whose full pathname is given in parameter 3.  If usePathname is false, WriteToFile invokes standard file with the contents of parameter 3 given as the default name for the file.  If standard file is invoked and the user pushes the cancel button in the dialog box, FileToField returns "Cancel" as the Result.
  95.  
  96. If the fourth parameter, append, is TRUE, WriteToFile appends to the file rather than replacing its contents.  Note that this parameter has no significance unless the WriteToFile is writing to an existing file designated by full pathname.
  97.  
  98. If you want to be able to open your favorite word processor by double-clicking in the Finder on the text file that WriteToFile creates, you must supply the creator parameter.  For MacWrite, the creator is "MACA."  For Microsoft Word, the creator is "MSWD."  If you don't specify a creator, WriteToFile will default to MACA.  Note that this parameter is not significant unless WriteToFile is creating a new file.  The creator of an existing file will not be changed.
  99.  
  100. EXAMPLES
  101.  
  102. WriteToFile bkgnd field id 3    -- standard file will be invoked
  103. WriteToFile card field 5,TRUE,"TheFattaTheLand:Of Mice And Men:My Book Report" 
  104. WriteToFile variableName,TRUE,"MyHD:MyFile",TRUE    -- append to existing file
  105.  
  106. REVISION HISTORY
  107. 30 April 1989   1.0
  108.  
  109. NOTE TO USERS OF FIELDTOFILE:  WriteToFile does everything that FieldToFile could do, except that it can't write to an AppleShare drop folder.  The parameter list is quite different; the most important difference is that, when using WriteToFile, you must not put a field designation in quotation marks.
  110.  
  111. -- part contents for card part 7
  112. ----- text -----
  113. UNIT DisksEngravedWhileUWait;
  114.  
  115. { WriteToFile XCMD ┬⌐ 1988-1989 by the Trustees of Dartmouth College }
  116. { Written by Kevin Calhoun }
  117.  
  118. { This source compatible with MPW Pascal 3.0 }
  119.  
  120. (*
  121. Pascal WriteToFile.p
  122. Link -m ENTRYPOINT Γêé
  123.      -o "YourFile" Γêé
  124.      -rt XCMD=2240 Γêé
  125.      -sn Main=WriteToFile Γêé
  126.      WriteToFile.p.o Γêé
  127.     "{Libraries}"interface.o Γêé
  128.     "{PLibraries}"Paslib.o Γêé
  129.     "{Libraries}"HyperXLib.o
  130. *)
  131.  
  132. {$R-}
  133. INTERFACE
  134.   USES
  135.     Types,
  136.     Memory,
  137.     Files,
  138.     Resources,
  139.     Errors,
  140.     Packages,
  141.     HyperXCmd;
  142.  
  143.   PROCEDURE EntryPoint (paramPtr : XCMDPtr);
  144.  
  145. IMPLEMENTATION
  146.  
  147.   PROCEDURE ContainerToFile (paramPtr: XCMDPtr);  FORWARD;
  148.  
  149.   PROCEDURE EntryPoint (paramPtr : XCMDPtr);
  150.   BEGIN
  151.     ContainerToFile(paramPtr);
  152.   END;
  153.  
  154.   FUNCTION GetScreenBitsBounds: Rect;
  155.   { get screenbits.bounds from the QuickDraw globals }
  156.   TYPE
  157.     LongwordPtr = ^LONGINT;
  158.     BitMapPtr = ^BitMap;
  159.   CONST
  160.     screenBitsOffset = -122;
  161.     CurrentA5 = $904;
  162.   VAR
  163.     screenBitsPtr : BitMapPtr;
  164.     myLongwordPtr : LongwordPtr;
  165.   BEGIN
  166.     myLongwordPtr := LongwordPtr(CurrentA5);
  167.       { myLongwordPtr now points to the pointer to the first QD global }
  168.     myLongwordPtr := LongwordPtr(myLongwordPtr^);
  169.       { myLongwordPtr now points to the first QD global }
  170.     screenBitsPtr := BitMapPtr(myLongwordPtr^ + screenBitsOffset);
  171.       { screenBitsPtr now points to the screenBits BitMap }
  172.     GetScreenBitsBounds := screenBitsPtr^.bounds;
  173.   END;
  174.  
  175.   FUNCTION BuildThePathname (fName : Str255;
  176.                   vRefNum : INTEGER) : Str255;
  177. { Given the "short name" and vRefNum of a file, returns the full pathname. }
  178. { This function is adapted from Steve Maller's FileName XFCN published in }
  179. { HyperTalk Programming by Dan Shafer, Howard W. Sams & Company, 1988, }
  180. { pp. 399-403. }
  181.     VAR
  182.       name, fullPathName : Str255;
  183.       err : INTEGER;
  184.       myWDPB : WDPBPtr;
  185.       myCPB : CInfoPBPtr;
  186.       myPB : HParmBlkPtr;
  187.  
  188.   BEGIN
  189.     fullPathName := '';     { start with an empty pathname }
  190. { Allocate some memory in the heap for the parameter block. }
  191.     myCPB := CInfoPBPtr(NewPtr(SizeOf(HParamBlockRec)));
  192.     IF ord4(myCPB) > 0 THEN    { continue if mem allocation was OK }
  193.  
  194.       BEGIN
  195.         myWDPB := WDPBPtr(myCPB);
  196.         myPB := HParmBlkPtr(myCPB);
  197. { same pointer, different variations of the record -- see IM IV, p. 117 }
  198.         name := '';     { start with an empty name for the volume }
  199.  
  200.         WITH myPB^ DO
  201.           BEGIN
  202.             ioNamePtr := @name;   { we want the volume name }
  203.             ioCompletion := pointer(0);
  204.             ioVRefNum := vRefNum;  { returned by SFGetFile }
  205.             ioVolIndex := 0;  { use the vRefNum and name only to designate volume }
  206.           END;
  207.         err := PBHGetVInfo(myPB, FALSE);  { fill in the volume info }
  208.         IF err = noErr THEN
  209.  
  210.           BEGIN
  211. { Now we need the Working Directory (WD) information because we're }
  212. { going to step backwards from the file through all of the folders until }
  213. { we reach the root directory. }
  214.             WITH myWDPB^ DO
  215.               BEGIN
  216.                 ioVRefNum := vRefNum;  { this got set to 0 above }
  217.                 ioWDProcID := 0;   { use the vRefNum }
  218.                 ioWDIndex := 0;     { we want all directories }
  219.               END;
  220.             err := PBGetWDInfo(myWDPB, FALSE);
  221.             IF err = noErr THEN
  222.               BEGIN
  223.                 WITH myCPB^ DO
  224.                   BEGIN
  225.                     ioFDirIndex := -1;   { use the ioDirID field only }
  226.                     ioDrDirID := myWDPB^.ioWDDirID;   { info returned above }
  227.                   END;
  228.                 err := PBGetCatInfo(myCPB, FALSE);
  229.                 IF err = noErr THEN
  230.                   BEGIN
  231.  
  232. { Here starts the real work -- start to climb the tree by continually }
  233. { looking in the ioDrParID field for the next directory above until we fail... }
  234.                     myCPB^.ioDrDirID := myCPB^.ioDrParID;  { the first folder }
  235.                     fullPathName := CONCAT(myCPB^.ioNamePtr^, ':', fName);
  236.                     REPEAT
  237.                       myCPB^.ioDrDirID := myCPB^.ioDrParId;
  238.                       err := PBGetCatInfo(myCPB, FALSE);    { the next level }
  239. { Be careful of an error returned here -- it means the user chose a file on the }
  240. { desktop level of this volume.  If this is the case, just stop here and return }
  241. { "VolumeName:FileName"; otherwise loop until failure. }
  242.                       IF err = noErr THEN
  243.                         fullPathName := CONCAT(myCPB^.ioNamePtr^, ':', fullPathName);
  244.                     UNTIL err <> noErr;
  245.                   END;  { if PBGetCatInfo worked OK }
  246.               END;  { if PBGetWDInfo worked OK }
  247.           END;  { if PBHGetVInfo worked OK }
  248.         DisposPtr(pointer(myCPB));
  249.       END;  { if we had enough room for a new pointer }
  250.     BuildThePathname := fullPathName;
  251.   END;
  252.  
  253.   PROCEDURE GetFileName(paramPtr:XCMDPtr; var str:Str255);
  254.   BEGIN
  255.     IF paramPtr^.paramCount > 2 THEN ZeroToPas(paramPtr, paramPtr^.params[3]^, str)
  256.     ELSE str := '';
  257.   END;
  258.     
  259.   PROCEDURE GetCreator(paramPtr: XCMDPtr; VAR creator: OSType);
  260.   VAR
  261.     str: Str255;
  262.   BEGIN
  263.     IF paramPtr^.paramCount > 4 THEN
  264.       BEGIN
  265.         str := '    ';
  266.         ZeroToPas(paramPtr, paramPtr^.params[5]^, str);
  267.         BlockMove(Ptr(ORD4(@str)+1),@creator,4);
  268.       END
  269.     ELSE creator := 'MACA';
  270.   END;
  271.  
  272.   FUNCTION GotFileFromSFPut(var volume: INTEGER; var fileName: Str255): BOOLEAN;
  273.   VAR
  274.     where : Point;
  275.     reply : SFReply;
  276.     dlgt: DialogTHndl;
  277.     r: rect;
  278.     screen: rect;
  279.     h, v: INTEGER;
  280.   BEGIN
  281.     dlgt := DialogTHndl(GetResource('DLOG',putDlgID));
  282.     if dlgt <> nil then
  283.       begin
  284.       r := dlgt^^.boundsRect;
  285.       screen := GetScreenBitsBounds;
  286.       h := ((screen.right - screen.left) - (r.right - r.left)) div 2;
  287.       v := ((screen.bottom - screen.top) - (r.bottom - r.top)) div 2;
  288.       SetPt(where, h, v);
  289.       end
  290.     else SetPt(where, 82, 75);
  291.     SFPutFile(where, '', fileName, NIL, reply);
  292.     WITH reply DO
  293.       BEGIN
  294.       IF good THEN
  295.         BEGIN
  296.         fileName := fName;
  297.         volume := vRefNum;
  298.         END;
  299.       GotFileFromSFPut := good;
  300.       END;
  301.   END;
  302.   
  303.   FUNCTION FlushVolOfFile(fRefNum: INTEGER): OSErr;
  304.     LABEL 99;
  305.     VAR
  306.       err: OSErr;
  307.       myFCBPBHndl: Handle;
  308.       myFCBPBPtr: FCBPBPtr;
  309.   BEGIN
  310.     err := noErr;
  311.     myFCBPBHndl := NewHandleClear(SIZEOF(FCBPBRec));
  312.     err := MemError;
  313.     IF err <> noErr THEN GOTO 99;
  314.     
  315.     MoveHHi(myFCBPBHndl);
  316.     HLock(myFCBPBHndl);
  317.     
  318.     myFCBPBPtr := FCBPBPtr(myFCBPBHndl^);
  319.     myFCBPBPtr^.ioRefNum := fRefNum;
  320.     err := PBGetFCBInfo(myFCBPBPtr, FALSE);
  321.     IF err=noErr THEN err := FlushVol(NIL,myFCBPBPtr^.ioVRefNum);
  322.     
  323.     DisposHandle(myFCBPBHndl);
  324.     99: FlushVolOfFile := err;
  325.   END;
  326.  
  327.   FUNCTION WriteToFile(vRefNum: INTEGER; fileName: Str255;
  328.                        textPtr: Ptr; VAR count: LONGINT;
  329.                        creator: OSType; append: BOOLEAN): OSErr;
  330.     LABEL
  331.       98,99;
  332.     VAR
  333.       err: OSErr;
  334.       fRefNum: INTEGER;
  335.       fileLength: LONGINT;
  336.   BEGIN
  337.     err := Create(fileName,vRefNum,creator,'TEXT');
  338.     IF (err <> noErr)&(err<>dupFNErr) THEN GOTO 99;
  339.  
  340.     err := FSOpen(fileName,vRefNum,fRefNum);
  341.     IF err <> noErr THEN GOTO 99;
  342.  
  343.     IF append THEN
  344.       BEGIN
  345.       err := GetEOF(fRefNum,fileLength);
  346.       IF err <> noErr THEN GOTO 98;
  347.       END
  348.     ELSE fileLength := 0;
  349.     err := SetFPos(fRefNum,fsFromStart,fileLength);
  350.     IF err <> noErr THEN GOTO 98;
  351.     
  352.     err := FSWrite(fRefNum, count, textPtr);
  353.     IF err<>noErr THEN GOTO 98;
  354.  
  355.     err := SetEOF(fRefNum, fileLength+count);
  356.     err := FlushVolOFFile(fRefNum);
  357.  
  358.     98: err := FSClose(fRefNum);
  359.     99: WriteToFile := err;
  360.   END;
  361.  
  362.   PROCEDURE ContainerToFile (paramPtr : XCMDPtr);
  363.     LABEL 100;
  364.     VAR
  365.       theText: Handle;
  366.       str: Str255;
  367.       vRefNum: INTEGER;
  368.       usePathName: BOOLEAN;
  369.       creator: OSType;
  370.       append: BOOLEAN;
  371.       hs: SignedByte;
  372.       theLength: LONGINT;
  373.       err : OSErr;
  374.  
  375.     PROCEDURE PassReturnValue (theMsg : Str255); { set theResult and quit }
  376.     BEGIN
  377.       paramPtr^.returnValue := PasToZero(paramPtr, theMsg);
  378.     END;
  379.  
  380.   BEGIN
  381.     err := noErr;
  382.     IF paramPtr^.paramCount < 1 THEN
  383.       BEGIN
  384.       PassReturnValue('WriteToFile XCMD 1.0, 30 April 1989, ┬⌐1988-1989 Dartmouth College');
  385.       GOTO 100;
  386.       END;
  387.  
  388.     theText := paramPtr^.params[1];
  389.     usePathName := FALSE;
  390.     IF paramPtr^.paramCount > 1 THEN
  391.       BEGIN
  392.       ZeroToPas(paramPtr,paramPtr^.params[2]^,str);
  393.       usePathName := StrToBool(paramPtr,str);
  394.       END;
  395.       
  396.     append := FALSE;
  397.     IF paramPtr^.paramCount > 3 THEN
  398.       BEGIN
  399.       ZeroToPas(paramPtr,paramPtr^.params[4]^,str);
  400.       append := StrToBool(paramPtr,str);
  401.       END;
  402.       
  403.     GetFileName(paramPtr,str);
  404.     IF usePathName THEN
  405.       BEGIN
  406.       vRefNum := 0;
  407.       IF LENGTH(str) = 0 THEN
  408.         BEGIN
  409.         err := bdNamErr;
  410.         GOTO 100;
  411.         END;
  412.       END
  413.     ELSE
  414.       IF NOT GotFileFromSFPut(vRefNum,str) THEN
  415.         BEGIN
  416.         PassReturnValue('Cancel');
  417.         GOTO 100;
  418.         END;
  419.  
  420.     GetCreator(paramPtr,creator);
  421.     hs := HGetState(theText);
  422.     HLock(theText);
  423.     theLength := StringLength(paramPtr, theText^);
  424.     err := WriteToFile(vRefNum,str,theText^,theLength,creator,append);
  425.     HSetState(theText,hs);
  426.     IF NOT usePathName THEN str := BuildThePathName(str,vRefNum); 
  427.     PassReturnValue(str);
  428.  
  429.     100: IF err <> noErr THEN
  430.       BEGIN
  431.       NumToStr(paramPtr,err,str);
  432.       PassReturnValue(CONCAT('Error ',str));
  433.       END;
  434.   END;
  435.  
  436. END.